<?php
/**
 * CreateTime: 2024/1/3 11:24
 * User:LinQ
 */

namespace App\Func\Jobs;

use App\Facade\UserFuncFacade;
use App\Models\System\JobsModel;
use App\Models\Users\UsersModel;
use Symfony\Component\Process\Process;

class JobsDockerFunc
{
    private $dockers;
    private $docker_nums;

    public function __construct()
    {
        $dockerInfo = config('c_docker');
        $dockers = $dockerInfo['dockers'];

        // 进行简单的健康监测
        foreach($dockers as $key=>$docker){
            try {
                $process = new Process(['docker','container','inspect','--format={{.State.Status}}',$key]);
                $process->run();
                $r = $process->getOutput();
                $r = trim($r,"\n");
                if($r!='running'){
                    s_fail_return(null,$key.'健康检查失败');
                }
                if (!$process->isSuccessful()) {
                    s_fail_return(null,$key.'健康检查失败');
                }
            } catch (\Exception $e) {
                s_fail_return(null,$key.'健康检查失败');
            }
        }
        $this->dockers = $dockers;
        $this->docker_nums = count($dockers);
    }

    public function pushJobs($func,$queueName,$jobsDescribe,$groupId){
        dispatch($func)->onQueue($queueName);
        $jobsModel = new JobsModel();
        // 检查当前分组名称是否已经存在了
        $canExists= $jobsModel->select(['jobs_id'])->where(
            [
                'jobs_group_id' => $groupId
            ]
        )->first();
        if($canExists){
            $jobsModel->select(['jobs_id'])->where(
                [
                    'jobs_group_id' => $groupId
                ]
            )->increment('sum');
        }else{
            $jobsModel->insertGetId([
                'queue_name' => $queueName,
                'jobs_describe' => $jobsDescribe,
                'jobs_group_id' => $groupId,
                'sum' => 1,
                'flash' => 0,
                'fail' => 0,
                'created_at' => date('Y-m-d h:i:s'),
                'updated_at' => date('Y-m-d h:i:s'),
            ]);
        }
    }

    /**
     * 虚假的负载均衡算法
     * @return mixed
     */
    public function calculateSum(): mixed
    {
        // 获取所有健康容器中排队的值数量
        $query = (new JobsModel())
            ->selectRaw('queue_name,SUM(`sum` - `flash` - `fail`) as total')
            ->whereIn('queue_name', array_keys($this->dockers))
            ->groupBy('queue_name')
            ->get()
            ->toArray();
        // 找到最大的total
        $maxTotal = max(array_column($query, 'total'));
        $result = [];
        // 如果存在相同的值则保存
        foreach ($query as $item) {
            if ($item['total'] == $maxTotal) {
                $result[] = $item;
            }
        }
        // 根据权重进行二次排序
        usort($result, function ($a, $b) {
            $weightA = $this->dockers[$b['queue_name']]['weight'];
            $weightB = $this->dockers[$a['queue_name']]['weight'];
            return $weightA - $weightB;
        });

        return $result[0];
    }


}